package com.digua.base.base

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.viewbinding.ViewBinding
import com.alibaba.fastjson2.JSON
import com.digua.base.listener.RegisterForActivityResultListener
import com.digua.base.util.AuthorizeUtil
import com.digua.base.util.LogUtil
import org.greenrobot.eventbus.EventBus
import java.io.Serializable
import java.lang.reflect.Method
import java.lang.reflect.ParameterizedType


open class Fragment<UI : ViewBinding> : androidx.fragment.app.Fragment(), RegisterForActivityResultListener {
    protected var context: Activity<*>? = null
    protected lateinit var ui: UI
    private lateinit var launcher: ActivityResultLauncher<Intent>
    private var callback: ActivityResultCallback<Intent>? = null
    protected var isShow = false
    protected var isBusMsg = false

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        AuthorizeUtil.checkFragment()
        try {
            val type = javaClass.genericSuperclass as ParameterizedType
            val cls = type.actualTypeArguments[0] as Class<*>
            val inflate: Method = cls.getDeclaredMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.javaPrimitiveType)
            ui = inflate.invoke(null, inflater, container, false) as UI
            launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { callback?.apply { onActivityResult(it.data!!) } }
            context = activity as Activity<*>?
            return ui.root
        } catch (e: Exception) {
            LogUtil.e("异常:", e)
        }
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        context = activity as Activity<*>?
        if (isBusMsg) EventBus.getDefault().register(this)
    }

    protected open fun startActivity(clz: Class<*>, data: Any? = null) {
        if (!AuthorizeUtil.checkActivity()) return
        val intent = Intent(activity, clz)
        data?.let {
            when (data) {
                is Serializable -> intent.putExtra("data", it as Serializable)
                is Intent -> intent.putExtras(it as Intent)
                is Bundle -> intent.putExtras(it as Bundle)
                else -> intent.putExtra("data", JSON.toJSONString(data))
            }
        }
        super.startActivity(intent)
    }

    protected open fun startActivityFinish(clz: Class<*>, data: Any? = null) {
        startActivity(clz, data)
        activity?.finish()
    }

    override fun registerForActivityResult(intent: Intent, callback: ActivityResultCallback<Intent>) {
        this.callback = callback
        launcher.launch(intent)
    }

    override fun onResume() {
        super.onResume()
        if (!isShow) {
            isShow = true
            onShow()
        }
    }

    override fun onPause() {
        super.onPause()
        if (isShow) {
            isShow = false
            onHide()
        }
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isVisibleToUser && !isShow) {
            isShow = true
            onShow()
        } else if (!isVisibleToUser && isShow) {
            isShow = false
            onHide()
        }
    }

    open fun onShow() {}

    open fun onHide() {}

    override fun onDestroy() {
        super.onDestroy()
        if (isBusMsg) EventBus.getDefault().unregister(this)
    }
}